package pers.xx.sbm.config;

/**
 * @author ：xiexing
 * @description：切面处理
 * @date ：2020/8/14 8:58
 */

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import pers.xx.sbm.entity.OptLog;
import pers.xx.sbm.entity.User;
import pers.xx.sbm.enums.ResultEnum;
import pers.xx.sbm.service.OptLogDetailService;
import pers.xx.sbm.service.OptLogService;
import pers.xx.sbm.utils.UserUtils;
import pers.xx.sbm.vo.ResResult;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Aspect
@Component
public class LogAspect {

    /**
     * slf4j日志
     */
    private final static Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Autowired
    private OptLogService optLogService;//日志接口

    @Autowired
    private OptLogDetailService optLogDetailService;//日志详情接口

    @Autowired
    private UserUtils userUtils;

    /**
     * Pointcut 切入点
     * 匹配cn.controller包下面的所有方法
     */
    @Pointcut("execution(public * pers.xx.sbm.controller.*.*(..))")
    public void webLog() {
    }

    /**
     * 环绕通知
     */
    @Around(value = "webLog()")
    public Object arround(ProceedingJoinPoint pjp) {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            assert attributes != null;
            HttpServletRequest request = attributes.getRequest();
//            OptLog optLog = saveLog(request, pjp);//保存日志基本信息并返回参数
//            if (optLog == null) {
//                return new ResResult(ResultEnum.SYSTEM_ERR, "日志保存失败");
//            }
//            String args = Arrays.toString(pjp.getArgs());//参数
//            args = args == null ? "" : args;
//            args = JSONObject.toJSONString(args);//转化为json
            Object o = pjp.proceed();
//            OptLogDetail optLogDetail = new OptLogDetail();
//            optLogDetail.setOptId(optLog.getId());
//            optLogDetail.setOptReqArgs(args);
            o = o == null ? "" : o;
//            optLogDetail.setOptResData(JSONObject.toJSONString(o));
//            optLogDetailService.insertSelective(optLogDetail);
            return o;
        } catch (Throwable e) {
            logger.error(pjp.getSignature() + " 出现异常： ", e);
            return new ResResult(ResultEnum.SYSTEM_ERR, e.getMessage());
        }
    }

    /**
     * 方法执行前
     */
    @Before(value = "webLog()")
    public void before(JoinPoint joinPoint) throws Exception {
    }

    /**
     * 方法执行结束，不管是抛出异常或者正常退出都会执行
     */
    @After(value = "webLog()")
    public void after(JoinPoint joinPoint) {
    }

    /**
     * 方法执行结束，增强处理
     */
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) {

    }

    /**
     * 后置异常通知
     */
    @AfterThrowing(value = "webLog()")
    public void throwss(JoinPoint joinPoint) {
    }


    /**
     * @description 保存日志信息
     * @author XieXing
     * @date 2020/9/1 15:08
     */

    public OptLog saveLog(HttpServletRequest request, JoinPoint joinPoint) {
        try {
            String url = request.getRequestURL().toString();//请求url
            String httpMethod = request.getMethod();//请求方式
            String ip = request.getRemoteAddr();//请求ip
            ip = ip != null && ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
            String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();//请求类方法
            OptLog optLog = new OptLog();
            optLog.setOptUrl(url);
            optLog.setOptHttpMethod(getMethodFalg(httpMethod));
            optLog.setOptIp(ip);
            optLog.setOptClassMethod(classMethod);
            User user = userUtils.getCurrentUser();
            int userId = 0;
            String userName = "未登录";
            if (user != null) {
                userId = user.getId();
                userName = user.getUserName();
            }
            optLog.setOptUserId(userId);
            optLog.setOptUserName(userName);
            optLog.setOptTime(new Date());
            optLogService.insertSelective(optLog);
            return optLog;
        } catch (Exception e) {
            logger.info("日志保存失败：" + e);
            return null;//代表异常
        }
    }


    /**
     * @description 获取请求方式表示
     * @author XieXing
     * @date 2020/9/1 22:44
     */
    private static int getMethodFalg(String method) {
        int flag;
        switch (method) {
            case "POST":
                flag = 2;
                break;
            case "PUT":
                flag = 3;
                break;
            case "DELETE":
                flag = 4;
                break;
            default:
                flag = 1;
                break;
        }
        return flag;
    }
}
